home *** CD-ROM | disk | FTP | other *** search
- /*
- ##########################################################################
- #### ####
- #### TurboDevice - A resident RAM disk for the Amiga ####
- #### ================================================= ####
- #### ####
- #### Format.c ####
- #### ####
- #### Version 1.00os -- May 04, 1991 ####
- #### ####
- #### Copyright (C) 1990 Thomas Dreibholz ####
- #### 1991 Molbachweg 7 ####
- #### 51674 Wiehl/Germany ####
- #### EMail: Dreibholz@bigfoot.com ####
- #### WWW: http://www.bigfoot.com/~dreibholz ####
- #### ####
- ##########################################################################
- */
- /***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
-
-
- #include <exec/types.h>
- #include <libraries/dos.h>
- #include <libraries/dosextens.h>
- #include <libraries/filehandler.h>
- #include <exec/memory.h>
- #include <exec/execbase.h>
- #include <exec/resident.h>
- #include <exec/devices.h>
- #include <exec/io.h>
- #include <exec/libraries.h>
- #include <devices/trackdisk.h>
-
- /* Resident-Informationen */
-
- #define MODULENAME "turbo.semaphore"
- #define IDSTRING "turbo.semaphore 33.0 (1 Aug 1991)\n"
- #define TURBO_NUMUNITS 50
- #define TURBO_VERSION 33
- #define TURBO_PRIORITY 39
-
- /* Interne Verwaltungsstrukturen */
-
- struct MemoryPtr
- {
- UBYTE *Address;
- ULONG Length;
- };
- struct TurboMod
- {
- struct MemChunk tm_OverwriteMe;
- APTR tm_ModuleTab[3];
- struct Resident tm_ROMTag;
- struct MemoryPtr tm_MemoryPtr[TURBO_NUMUNITS];
- struct MemList tm_ML;
- struct MemEntry tm_NextList[TURBO_NUMUNITS];
- UBYTE tm_ModuleName[20];
- UBYTE tm_IdString[40];
- };
- struct MatchTag
- {
- struct Resident mt_ROMTag;
- struct MemoryPtr mt_MemoryPtr[TURBO_NUMUNITS];
- struct MemList mt_ML;
- struct MemEntry mt_NextList[TURBO_NUMUNITS];
- UBYTE mt_ModuleName[20];
- UBYTE mt_IdString[40];
- };
- struct InfoTable
- {
- struct DeviceNode *DeviceNode;
- struct FileSysStartupMsg *FSSM;
- struct DosEnvec *DosEnvec;
- ULONG MemoryType;
- struct DosLibrary *DosBase;
- };
-
- /* Hauptstruktur des Devices */
-
- struct TurboDevice
- {
- struct Library Device;
- struct ExecBase *SysLib;
- struct DosLibrary *DosLib;
- APTR SegList;
- struct Resident *Resident;
- UBYTE Flags;
- UBYTE DriveNum;
- struct TurboUnit *Units[TURBO_NUMUNITS];
- };
- struct TurboDevMsg
- {
- struct Device *tdm_Device;
- struct Unit *tdm_Unit;
- };
- struct TurboUnit
- {
- struct Unit tu_Unit;
- UBYTE tu_UnitNum;
- UBYTE tu_pad;
- struct TurboDevMsg tu_Message;
- struct Process *tu_Process;
- LONG tu_LastComm;
- ULONG tu_Size;
- ULONG tu_NumTracks;
- ULONG tu_Position;
- };
-
- /* Flags für MountList */
-
- #define TDB_RAM 0L
- #define TDB_TYPE 1L
- #define TDF_RESIDENT 0L
- #define TDF_RAM (1L<<0)
- #define TDF_TYPE (1L<<1)
-
- /* Berechnungsmacros */
-
- #define DE(x) (info.DosEnvec->x)
- #define TRACKS (((DE(de_HighCyl)+1)-DE(de_LowCyl))*DE(de_Surfaces))
-
- /* Funktionsvordefinitionen */
-
- VOID ResetProg();
- VOID EndCode();
- UBYTE *GetMemory();
- ULONG GetDriveSize();
- VOID RootBlockCheckSum();
- VOID AllocBitMapBlock();
- VOID FreeBitMapBlock();
- VOID CalcBitMapCheckSum();
- ULONG CalcRootBlock();
- ULONG CalcBitMap();
- ULONG CalcBlocks();
- VOID InstallRootBlock();
- VOID Format();
-
- /* ================================================== */
- /* == GetMemory == */
- /* == Beschafft und installiert Speicher == */
- /* == Parameter: == */
- /* == => EBase: Zeiger auf ExecBase == */
- /* == => Device: Zeiger auf TurboDevice == */
- /* == => Unit: Unitnummer == */
- /* == => TurboUnit: Zeiger auf Unit == */
- /* == <= Kapazität des Units == */
- /* ================================================== */
-
- UBYTE *GetMemory(EBase,Device,Unit,TurboUnit)
- struct ExecBase *EBase;
- struct TurboDevice *Device;
- ULONG Unit;
- struct TurboUnit *TurboUnit;
- {
- register struct TurboMod *tm;
- register struct Resident *res;
- register struct MatchTag *mt;
- UBYTE *copydest,*copysrc;
- register UBYTE *mem;
- register ULONG Size;
- struct InfoTable info;
-
- info.DosBase=OpenLibrary("dos.library",0L);
- res=FindResident(MODULENAME);
- if(res==NULL) res=Device->Resident;
- if(res!=NULL)
- {
- mt=(struct MatchTag *)res->rt_MatchTag;
- mem=mt->mt_MemoryPtr[Unit].Address;
- if(mem==NULL)
- {
- Size=GetDriveSize(FindTask(NULL),Unit,&info);
- if(Size==NULL) return(NULL);
- Size+=8;
- mem=AllocMem(Size,info.MemoryType);
- if(mem==NULL) return(NULL);
- TurboUnit->tu_Size=Size-8;
- TurboUnit->tu_NumTracks=TRACKS;
- if(info.FSSM->fssm_Flags & TDF_RAM)
- {
- mem=mem+8;
- Format(mem,&info,Device->DriveNum);
- Device->DriveNum++;
- return(mem);
- }
- mt->mt_MemoryPtr[Unit].Address=mem+8;
- mt->mt_MemoryPtr[Unit].Length=Size-8;
- mt->mt_ML.ml_ME[mt->mt_ML.ml_NumEntries].me_Addr=mem;
- mt->mt_ML.ml_ME[mt->mt_ML.ml_NumEntries].me_Length=Size;
- mt->mt_ML.ml_NumEntries++;
- Forbid();
- #asm
- movem.l d0/a6,-(sp)
- move.l $4,a6
- jsr -612(a6)
- move.l d0,554(a6)
- movem.l (sp)+,d0/a6
- #endasm
- Permit();
- mem=mem+8;
- Format(mem,&info,Device->DriveNum);
- Device->DriveNum++;
- }
- return(mem);
- }
- Size=GetDriveSize(FindTask(NULL),Unit,&info);
- if(Size==NULL) return(NULL);
- Size+=8;
- mem=AllocMem(Size,info.MemoryType);
- if(mem==NULL)
- {
- return(NULL);
- }
- TurboUnit->tu_Size=Size-8;
- if(info.FSSM->fssm_Flags & TDF_RAM) return(mem+8);
- tm=AllocMem(sizeof(struct TurboMod)+((ULONG)EndCode-(ULONG)ResetProg),MEMF_CHIP|MEMF_CLEAR|MEMF_PUBLIC);
- if(tm==NULL)
- {
- Size-=8;
- FreeMem(mem,Size);
- return(NULL);
- }
- tm->tm_ROMTag.rt_MatchWord=RTC_MATCHWORD;
- tm->tm_ROMTag.rt_MatchTag=&tm->tm_ROMTag;
- tm->tm_ROMTag.rt_EndSkip=(APTR)((UBYTE *)tm+sizeof(struct TurboMod))+((ULONG)EndCode-(ULONG)ResetProg);
- tm->tm_ROMTag.rt_Flags=RTF_COLDSTART;
- tm->tm_ROMTag.rt_Version=TURBO_VERSION;
- tm->tm_ROMTag.rt_Type=NT_SEMAPHORE;
- tm->tm_ROMTag.rt_Pri=TURBO_PRIORITY;
- tm->tm_ROMTag.rt_Name=tm->tm_ModuleName;
- tm->tm_ROMTag.rt_IdString=tm->tm_IdString;
- tm->tm_ROMTag.rt_Init=(APTR)((UBYTE *)tm+sizeof(struct TurboMod));
- tm->tm_ML.ml_NumEntries=2;
- tm->tm_ML.ml_Node.ln_Type=NT_MEMORY;
- tm->tm_ML.ml_ME[0].me_Addr=(APTR)tm;
- tm->tm_ML.ml_ME[0].me_Length=sizeof(struct TurboMod)+((ULONG)EndCode-(ULONG)ResetProg);
- tm->tm_ML.ml_ME[1].me_Addr=mem;
- tm->tm_ML.ml_ME[1].me_Length=Size;
- tm->tm_MemoryPtr[Unit].Address=mem+8;
- tm->tm_MemoryPtr[Unit].Length=Size-8;
- strcpy(tm->tm_ModuleName,MODULENAME);
- strcpy(tm->tm_IdString,IDSTRING);
- copysrc=(UBYTE *)ResetProg;
- copydest=(UBYTE *)tm->tm_ROMTag.rt_Init;
- while(copysrc!=(UBYTE *)EndCode) *copydest++ = *copysrc++;
- Device->Resident=&tm->tm_ROMTag;
- Forbid();
- tm->tm_ModuleTab[0]=(APTR)&tm->tm_ROMTag;
- if(EBase->KickTagPtr)
- {
- tm->tm_ModuleTab[1]=(APTR)((ULONG)EBase->KickTagPtr|1<<31);
- }
- else
- {
- tm->tm_ModuleTab[1]=NULL;
- }
- if(EBase->KickMemPtr)
- {
- tm->tm_ML.ml_Node.ln_Succ=(struct Node *)EBase->KickMemPtr;
- }
- EBase->KickTagPtr=(APTR)tm->tm_ModuleTab;
- EBase->KickMemPtr=(APTR)&tm->tm_ML;
- #asm
- movem.l d0/a6,-(sp)
- move.l $4,a6
- jsr -612(a6)
- move.l d0,554(a6)
- movem.l (sp)+,d0/a6
- #endasm
- Permit();
- InitResident(&tm->tm_ROMTag,tm);
- mem=mem+8;
- Format(mem,&info,Device->DriveNum);
- Device->DriveNum++;
- return(mem);
- }
-
- /* ================================================== */
- /* == ResetProg == */
- /* == Diese Funktion läßt den Bildschirm für einen == */
- /* == kurzen Moment gelb werden, wenn das erste == */
- /* == resetfeste Unit installiert wird und wenn == */
- /* == ein resetfestes Unit bei einem Reset verfüg- == */
- /* == bar ist. Sollte trotz resetfestem Unit kein == */
- /* == gelber Bildschirm auftreten, so wurden die == */
- /* == Zeiger auf die resetfesten Strukturen == */
- /* == zerstört! Die in den Units gespeicherten == */
- /* == Daten sind Verloren! == */
- /* ================================================== */
-
- /* Anfang des resetfesten Bereichs */
-
- VOID ResetProg()
- {
- #asm
- move.l d0,-(sp) ; d0 retten
- bset #1,$bfe001 ; Power-LED ausschalten
- move.l #$10000,d0 ; $10000 nach d0
- 1$: ; Schleife
- move.w #$0FF5,$DFF180 ; Farbe gelb in Farbregister 0
- subq.l #1,d0 ; 1 von d0 abziehen
- tst.l d0 ; Ist d0=0 ?
- bne 1$ ; Nein, dann zu Schleife
- bclr #1,$bfe001 ; Power-LED einschalten
- move.l (sp)+,d0 ; d0 freigeben
- #endasm
- }
-
- /* Ende des resetfesten Bereichs */
-
- VOID EndCode() {} /* Markierung für Ende des Bereichs */
-
- /* ================================================== */
- /* == Format == */
- /* == Diese Routine formatiert den belegten == */
- /* == Speicher im AmigaDOS-Format. Sie wird nach == */
- /* == jeder Belegung aufgerufen. == */
- /* ================================================== */
-
- VOID Format(amem,info,number)
- ULONG amem;
- struct InfoTable *info;
- ULONG number;
- {
- REGISTER ULONG a,b,c,d;
- REGISTER UBYTE *bmem;
- REGISTER ULONG cmem;
- UBYTE Name[15];
- bmem=(UBYTE *)amem;
- bmem[0]='D';
- bmem[1]='O';
- bmem[2]='S';
- bmem[3]=0x00;
- a=CalcRootBlock(info->DosEnvec);
- b=CalcBitMap(info->DosEnvec);
- cmem=amem+(a*512L);
- strcpy(&Name,"Turbo #xy");
- if(number>9)
- {
- c=number/10;
- Name[7]=c+0x30;
- c=number%10;
- Name[8]=c+0x30;
- }
- else
- {
- Name[7]=number+0x30;
- Name[8]=0x00;
- }
- InstallRootBlock(info->DosBase,cmem,&Name,b);
- cmem=amem+(b*512);
- d=CalcBlocks(info->DosEnvec);
- for(c=2;c<=d;c++)
- {
- FreeBitMapBlock(c,cmem);
- }
- AllocBitMapBlock(a,cmem);
- AllocBitMapBlock(b,cmem);
- CalcBitMapCheckSum(cmem);
- }
-
- /* ================================================== */
- /* == GetDriveSize == */
- /* == Kapazität des Units ermitteln == */
- /* == Parameter: == */
- /* == => DosBase: Zeiger auf DosLibrary == */
- /* == => Task: Zeiger auf Unit-Task == */
- /* == => Unit: Unitnummer == */
- /* == => Info: Zeiger auf InfoTable == */
- /* == <= Kapazität == */
- /* ================================================== */
-
- ULONG GetDriveSize(task,unit,info)
- ULONG task;
- ULONG unit;
- struct InfoTable *info;
- {
- register struct DosBase *DosBase;
- register struct DeviceNode *DeviceNode;
- register struct RootNode *RootNode;
- register struct DosInfo *DosInfo;
- register struct FileSysStartupMsg *FSSM;
- register struct DosEnvec *DosEnvec;
- register ULONG size;
-
- DosBase=info->DosBase;
- task=task+92;
- size=64*1024*1024;
- RootNode=DosBase->dl_Root;
- DosInfo=BADDR(RootNode->rn_Info);
- DeviceNode=BADDR(DosInfo->di_DevInfo);
- do
- {
- if(DeviceNode->dn_Type==DLT_DEVICE)
- {
- if(DeviceNode->dn_Task==task)
- {
- FSSM=BADDR(DeviceNode->dn_Startup);
- if(FSSM->fssm_Unit==unit)
- {
- DosEnvec=BADDR(FSSM->fssm_Environ);
- size=(DosEnvec->de_HighCyl+1)-DosEnvec->de_LowCyl;
- size=size*DosEnvec->de_BlocksPerTrack;
- size=size*DosEnvec->de_Surfaces;
- size=size*DosEnvec->de_SizeBlock*4;
- size=size+(DosEnvec->de_Reserved*DosEnvec->de_SizeBlock*4);
- size=size+(DosEnvec->de_PreAlloc*DosEnvec->de_SizeBlock*4);
- info->DeviceNode=DeviceNode;
- info->FSSM=FSSM;
- info->DosEnvec=DosEnvec;
- if(FSSM->fssm_Flags & TDF_TYPE)
- {
- switch(DosEnvec->de_BufMemType)
- {
- case 2:
- case 3:
- info->MemoryType=MEMF_CLEAR|MEMF_PUBLIC|MEMF_CHIP;
- break;
- case 4:
- case 5:
- info->MemoryType=MEMF_CLEAR|MEMF_PUBLIC|MEMF_FAST;
- break;
- default:
- info->MemoryType=MEMF_CLEAR|MEMF_PUBLIC;
- break;
- }
- }
- else
- {
- info->MemoryType=MEMF_CLEAR|MEMF_PUBLIC;
- }
- DeviceNode=NULL;
- }
- else
- {
- DeviceNode=BADDR(DeviceNode->dn_Next);
- }
- }
- else
- {
- DeviceNode=BADDR(DeviceNode->dn_Next);
- }
- }
- else
- {
- DeviceNode=BADDR(DeviceNode->dn_Next);
- }
- }
- while(DeviceNode!=0L);
- return(size);
- }
-
- VOID RootBlockCheckSum(buf)
- UBYTE *buf;
- {
- ULONG checksum,*long_ptr;
- LONG i;
- long_ptr=(ULONG *)buf;
- checksum=0;
- for(i=0;i<TD_SECTOR/4;i++)
- {
- checksum+=long_ptr[i];
- }
- long_ptr[5]-=checksum;
- }
-
- VOID InstallRootBlock(DBase,buf,diskname,bitmap)
- struct DosLibrary *DBase;
- UBYTE *buf;
- UBYTE *diskname;
- ULONG bitmap;
- {
- ULONG *long_ptr;
- LONG i;
- long_ptr=(ULONG *)buf;
- long_ptr[0] = 2L;
- long_ptr[3] = 72L;
- long_ptr[78] = -1L;
- long_ptr[79] = bitmap;
- long_ptr[127] = 1L;
- DateStamp(DBase,&long_ptr[121]);
- DateStamp(DBase,&long_ptr[105]);
- buf[432]=(UBYTE)strlen(diskname);
- for(i=0;i<strlen(diskname);i++)
- {
- buf[433+i]=diskname[i];
- }
- RootBlockCheckSum(buf);
- }
-
- ULONG CalcRootBlock(env)
- struct DosEnvec *env;
- {
- return((env->de_HighCyl+1)*env->de_Surfaces*env->de_BlocksPerTrack/2);
- }
-
- ULONG CalcBitMap(env)
- struct DosEnvec *env;
- {
- return((CalcRootBlock(env)+1));
- }
-
- ULONG CalcBlocks(env)
- struct DosEnvec *env;
- {
- return((env->de_HighCyl+1)*env->de_Surfaces*env->de_BlocksPerTrack-1);
- }
-
- VOID AllocBitMapBlock(block,buf)
- LONG block;
- UBYTE *buf;
- {
- ULONG *long_ptr=(ULONG *)buf;
- REGISTER LONG longword,bit;
- longword=(block-2)/32;
- bit=block-2-longword*32;
- long_ptr[longword+1] &= (0xFFFFFFFF-(1L<<bit));
- }
-
- VOID FreeBitMapBlock(block,buf)
- LONG block;
- UBYTE *buf;
- {
- ULONG *long_ptr=(ULONG *)buf;
- REGISTER LONG longword,bit;
- longword=(block-2)/32;
- bit=block-2-longword*32;
- long_ptr[longword+1] |= (1L<<bit);
- }
-
- VOID CalcBitMapCheckSum(buf)
- UBYTE *buf;
- {
- REGISTER ULONG checksum,i;
- ULONG *long_ptr=(ULONG *)buf;
- for(i=1,checksum=0;i<TD_SECTOR/4;i++) checksum+=long_ptr[i];
- long_ptr[0]=-checksum;
- }
-
-